﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using Microsoft.SharePoint;
using System.Threading;
using System.IO;

namespace showDocumentLibraryList
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
            //call setup first after InitializeComponent to set everything up
            setup();
            
        }

        
        private static Form2 nfrom2 = new Form2();
        private bool head = false;
        private StringBuilder documentLibList = new StringBuilder();
        private List<string> libID = new List<string>();

        private void setup()
        {
            // Set the view to show details.
            this.lvResult.View = View.Details;
            // Allow the user to edit item text.
            this.lvResult.LabelEdit = true;
            // Allow the user to rearrange columns.
            this.lvResult.AllowColumnReorder = true;
            // Display check boxes.
            this.lvResult.CheckBoxes = true;
            // Display grid lines.
            this.lvResult.GridLines = true;
            //create columns
            this.lvResult.Columns.Add("Title", -2 ,HorizontalAlignment.Left);
            this.lvResult.Columns.Add("Path", -2, HorizontalAlignment.Left);
            this.lvResult.Columns.Add("Site Title", -2, HorizontalAlignment.Left);
            this.lvResult.Columns.Add("Versioning", -2, HorizontalAlignment.Left);
            this.lvResult.Columns.Add("Hidden", -2, HorizontalAlignment.Left);
            this.lvResult.Columns.Add("ID", -2, HorizontalAlignment.Left);
            this.lvResult.Columns.Add("Allow Deletion", -2, HorizontalAlignment.Left);
            this.lvResult.Columns.Add("Date Created", -2, HorizontalAlignment.Left);
            //disable the button on first loading
            this.btnGo.Enabled = false;
            this.btnClear.Enabled = false;
            ((Control)this.tpSearch).Enabled = false;
        }
        
        private void button1_Click(object sender, EventArgs e)
        {
            lvResult.Items.Clear();
            
            //create a new thread to a method that shows form2, this is needed as the first(main thread) is busy
            //with the rest of the code, so this can be achived without hindering on the performance amd using 
            //ShowDialog();, without the thread the main form would be in a paused state and hangs up.
            System.Threading.Thread maint = new Thread(new ThreadStart(WorkThreadFunction));

            try
            {
                //quick check to make sure there is an input and carry on else show message
                if (txtURL.Text.Equals(""))
                {
                    MessageBox.Show("Please enter a vaild url");
                }
                else
                {
                    string http;
                    if (cbHTTPS.Checked == true)
                    {
                        http = "https://";
                    }
                    else
                    {
                        http = "http://";
                    }

                    //whilst searching disable the parent form
                    this.Enabled = false;
                    //set this form to invisable
                    this.Visible = false;
                    //start the thread to show loading form
                    maint.Start();

                    //get the manualy added url for the spsite
                    using (SPSite site = new SPSite(http + txtURL.Text))
                    {
                        //open the web object form the site object
                        using (SPWeb web = site.OpenWeb())
                        {
                            //call this method to write to the list and/or save to file
                            listLists(web);
                        }
                    }
                }

                //stop the other thread(loading) and show the partent form
                maint.Interrupt();
                maint.Abort();
                this.Enabled = true;
                this.Show();
                this.Refresh();
                if (lvResult.Items.Count > 0)
                {
                    this.btnSave.Enabled = true;
                    this.btnClear.Enabled = true;
                    ((Control)this.tpSearch).Enabled = true;
                    btnClear.Enabled = true;
                }
                else
                {
                    this.btnClear.Enabled = false;
                    this.btnSave.Enabled = false;
                    ((Control)this.tpSearch).Enabled = false;
                    btnClear.Enabled = false;
                }
                
            }
            catch(Exception ex)
            {
                //if there is an error like wrong url show this message
                MessageBox.Show("Sorry there is a problem: " + ex.Message);
                //set everythin back up so they can try again
                maint.Interrupt();
                maint.Abort();
                this.Enabled = true;
                this.Show();
                this.Refresh();
            }
        }

        /// <summary>
        /// mathod that is run in a seperate thread
        /// </summary>
        public static void WorkThreadFunction()
        {
            //show the loading form ShowDialog doesnt effect the main form as its running on another thread
            nfrom2.ShowDialog();
        }
        private List<string[]> listItems = new List<string[]>();
        private void listLists(SPWeb web)
        {
            //get the list collection using spbaseType so that it only only gets normal document
            //librarys but also custom document librarys
            SPListCollection ListColl = web.GetListsOfType(SPBaseType.DocumentLibrary);
            
            //loop through each list in the list collection
            foreach (SPList lst in ListColl)
            {
                //if the list isnt hiddent then carry on
                 if(!lst.Hidden)
                 {
                     //populate the list with the results
                     ListViewItem item = new ListViewItem(lst.Title);
                     item.SubItems.Add(web.Url);
                     item.SubItems.Add(web.Title);
                     item.SubItems.Add(lst.EnableVersioning.ToString());
                     item.SubItems.Add(lst.Hidden.ToString());
                     item.SubItems.Add(lst.ID.ToString());
                     item.SubItems.Add(lst.AllowDeletion.ToString());
                     item.SubItems.Add(lst.LastItemDeletedDate.ToString());
                     //add the items to the list
                     lvResult.Items.Add(item);


                     string[] values = new string[] { item.SubItems[0].Text, item.SubItems[1].Text, item.SubItems[2].Text, item.SubItems[3].Text, item.SubItems[4].Text, item.SubItems[5].Text, item.SubItems[6].Text, item.SubItems[7].Text };
                     
                     listItems.Add(values);

                     writetofile(lst.Title, web.Url, web.Title, lst.EnableVersioning.ToString());
                     
                 }        
            }

            //loop through each subweb of the web until there are no more subwebs
            foreach (SPWeb subWeb in web.Webs)
            {
                //call on itself for each subweb
                listLists(subWeb);
            }
        }

        /// <summary>
        /// enable/disable the button depending on any test entered
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void textBox1_TextChanged(object sender, EventArgs e)
        {
            if (txtURL.Text.Equals(""))
            {
                btnGo.Enabled = false;
            }
            else
            {
                btnGo.Enabled = true;
            }
        }

        private void writetofile(string title,string url, string sitetitle, string version)
        {
            if (head == false)
            {
                //write header title
                documentLibList.Append("Title" + "," + "URL" + "," + "Site Title" + "," + "Versioning" + Environment.NewLine + Environment.NewLine);
                head = true;
            }
            else
            {
                //write body content
                documentLibList.Append(title + "," + url + "," + sitetitle + "," + version + Environment.NewLine);
            }
        }

        private void saveFileToFile()
        {
            SaveFileDialog saveFileDialog1 = new SaveFileDialog();
            saveFileDialog1.Filter = "CSV|*.CSV";
            saveFileDialog1.Title = "Save a CSV File";

            if (saveFileDialog1.ShowDialog() == DialogResult.OK)
            {
                File.WriteAllText(saveFileDialog1.FileName, documentLibList.ToString());
            }
        }

        private void txtURL_KeyUp(object sender, KeyEventArgs e)
        {
            if (txtURL.Text.Contains("http://"))
            {
                txtURL.Text = txtURL.Text.Remove(0, 7);
            }
            if (txtURL.Text.Contains("https://")) 
            {
                txtURL.Text = txtURL.Text.Remove(0, 8);
            }
        }

        private void txtURL_MouseUp(object sender, MouseEventArgs e)
        {
            if (txtURL.Text.Contains("http://"))
            {
                txtURL.Text = txtURL.Text.Remove(0, 6);
            }
            if (txtURL.Text.Contains("https://"))
            {
                txtURL.Text = txtURL.Text.Remove(0, 8);
            }
        }

        private void btnSave_Click(object sender, EventArgs e)
        {
            saveFileToFile();
        }

        private void lvResult_ItemChecked(object sender, ItemCheckedEventArgs e)
        {
            if (searching != true)
            {
                string ID = this.lvResult.Items[e.Item.Index].SubItems[5].Text;
                string webURL = this.lvResult.Items[e.Item.Index].SubItems[1].Text;
                bool allowDelete = bool.Parse(this.lvResult.Items[e.Item.Index].SubItems[6].Text);
                if (e.Item.Checked == true)
                {
                    if (allowDelete == true)
                    {
                        if (!libID.Exists(delegate(string p) { return p.Trim() == ID; }))
                        {
                            libID.Add(ID + ";" + webURL + ";" + e.Item.Index);
                        }
                    }
                    else
                    {
                        e.Item.Checked = false;
                        MessageBox.Show("Sorry you cannot delete this library, please look at 'Allow Deletion column', if its set to true than you can delete.");
                    }
                }
                else
                {
                    if (libID.Exists(delegate(string p) { return p.Trim() == ID; }))
                    {
                        libID.Remove(ID + ";" + webURL + ";" + e.Item.Index);
                    }
                }
            }
        }

        private void lvResult_AfterLabelEdit(object sender, LabelEditEventArgs e)
        {
            string webURL = this.lvResult.Items[e.Item].SubItems[1].Text;
            using (SPSite mysite = new SPSite(webURL))
            {
                using (SPWeb web = mysite.OpenWeb())
                {
                    SPSecurity.RunWithElevatedPrivileges(delegate
                    {
                        System.Guid ID = new Guid(this.lvResult.Items[e.Item].SubItems[5].Text);
                        SPList List = web.Lists[ID];

                        List.Title = e.Label;

                        List.EnableVersioning = true;

                        List.Update();
                    });
                }
            }
        }

        private void btnClear_Click(object sender, EventArgs e)
        {
            lvResult.Items.Clear();
            this.btnSave.Enabled = false;
            ((Control)this.tpSearch).Enabled = false;
            btnClear.Enabled = false;
        }

        private bool searching = false;
        private void txtSearch_TextChanged(object sender, EventArgs e)
        {
            searching = true;
            if (txtSearch.Text.Length == 0)
            {
                lvResult.Items.Clear();
                foreach (string[] item in listItems)
                {
                    ListViewItem lvi = new ListViewItem(item[0]);
                    lvi.SubItems.Add(item[1]);
                    lvi.SubItems.Add(item[2]);
                    lvi.SubItems.Add(item[3]);
                    lvi.SubItems.Add(item[4]);
                    lvi.SubItems.Add(item[5]);
                    lvi.SubItems.Add(item[6]);
                    lvi.SubItems.Add(item[7]);
                    lvResult.Items.Add(lvi);
                }
            }
            else
            {
               
                lvResult.Items.Clear();
                foreach (string[] item in listItems)
                {
                    string Searchvalue = null;
                    if (rball.Checked == true)
                    {
                        for (int i = 0; i <= searchindex - 1; i++)
                        {
                            //Searchvalue = item[i].ToString();

                            bool containsValue = item[i].IndexOf(txtSearch.Text, StringComparison.OrdinalIgnoreCase) >= 0;
                            if (containsValue == true)
                            {
                                ListViewItem lvi = new ListViewItem(item[0]);
                                lvi.SubItems.Add(item[1]);
                                lvi.SubItems.Add(item[2]);
                                lvi.SubItems.Add(item[3]);
                                lvi.SubItems.Add(item[4]);
                                lvi.SubItems.Add(item[5]);
                                lvi.SubItems.Add(item[6]);
                                lvi.SubItems.Add(item[7]);
                                lvResult.Items.Add(lvi);
                                break;
                            }
                        }
                    }
                    else
                    {
                        Searchvalue = item[searchindex];

                        bool containsValue = item[searchindex].IndexOf(txtSearch.Text, StringComparison.OrdinalIgnoreCase) >= 0;
                        if (containsValue == true)
                        {
                            ListViewItem lvi = new ListViewItem(item[0]);
                            lvi.SubItems.Add(item[1]);
                            lvi.SubItems.Add(item[2]);
                            lvi.SubItems.Add(item[3]);
                            lvi.SubItems.Add(item[4]);
                            lvi.SubItems.Add(item[5]);
                            lvi.SubItems.Add(item[6]);
                            lvi.SubItems.Add(item[7]);
                            lvResult.Items.Add(lvi);

                        }
                    }
                }
            }
            searching = false;
        }

        private int searchindex = 0;

        private void rbTitle_CheckedChanged(object sender, EventArgs e)
        {
            searchindex = 0;
        }

        private void rbpath_CheckedChanged(object sender, EventArgs e)
        {
            searchindex = 1;
        }

        private void rbSiteTitle_CheckedChanged(object sender, EventArgs e)
        {
            searchindex = 2;
        }

        private void rbVers_CheckedChanged(object sender, EventArgs e)
        {
            searchindex = 3;
        }

        private void rbhidden_CheckedChanged(object sender, EventArgs e)
        {
            searchindex = 4;
        }

        private void rbID_CheckedChanged(object sender, EventArgs e)
        {
            searchindex = 5;
        }

        private void rbdel_CheckedChanged(object sender, EventArgs e)
        {
            searchindex = 6;
        }

        private void rbDate_CheckedChanged(object sender, EventArgs e)
        {
            searchindex = 7;
        }

        private void rball_CheckedChanged(object sender, EventArgs e)
        {
            searchindex = 8;
        }

    }
}
